Swift) Strategy Pattern이란?

Strategy Pattern

  • 클래스의 행위를 캡슐화 하여 동적으로 행위를 자유롭게 바꿀 수 있도록 돕는 패턴이다.

Strategy Pattern 구성요소 3가지

  1. Strategy를 사용할 객체
  2. Strategy를 정의하는 프로토콜
  3. 2번의 프로토콜을 구현한 Strategy객체

Strategy Pattern

두 개 이상의 유사한 동작이 필요하고, 이 동작이 유연하게 바뀌기를 원할 때 사용하면 좋다.
구성요소만 봐도 Delegate Pattern과 굉장히 유사하다는 것을 알 수 있다.

Strategy Pattern은 언제 사용하나요?

  • 어떤 상황에서 사용할 알고리즘이 여러 개 존재할 수 있을 때 사용하면 좋다.
    • 런타임에서 변경이 가능하기 때문에 이와 같은 상황에 효과적으로 대응할 수 있다.

ex) 네비게이션을 개발했다고 가정해보면?

  • 출시 당시, 자동차의 경로만 알려주는 내비게이션
  • 이후 사용자의 증가로 인해 도보로 이동하는 사람의 경로, 대중교통을 이동하는 사람의 경로 등 다양한 알고리즘이 필요
  • 하지만 이를 위해 클래스 안에 계속해서 구현하다 보면, 하나의 변경으로 인해 많은 곳을 수정해야 하는 문제가 발생한다.

이를 해결하기 위해 Strategy Pattern을 사용 할 수 있다.
자동차의 경로, 도보로 이동하는 경로, 대중교통 경로에 대한 알고리즘을 따로 구현하고 이들을 캡슐화한다.
각각의 알고리즘은 서로에게 영향을 주지 않고 각자 독립적으로 작동하도록 만들어주어 위와 같은 문제를 해결할 수 있다.

위의 예시를 예제로!

  • 먼저 Strategy 인터페이스 역할을 할 프로토콜을 하나 정의해준다.
1
2
3
4
// Strategy
protocol Strategy {
func algorithmExecute()
}
  • 그 다음으로는 Strategy 프로토콜을 채택하는 알고리즘들을 만들어준다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// 네비게이션으로 자동차, 도보, 자전거 경로를 알고 싶으니 Strategy 프로토콜을 채택한 3개의 클래스를 만들어준다.

// Concrete Strategy
class CarRoute: Strategy {
func algorithmExecute() {
print("자동차 경로 찾기 완료!\n")
}
}

// Concrete Strategy
class WalkRoute: Strategy {
func algorithmExecute() {
print("도보 경로 찾기 완료!\n")
}
}

// Concrete Strategy
class BikeRoute: Strategy {
func algorithmExecute() {
print("자전거 경로 찾기 완료!\n")
}
}
  • 만든 알고리즘들을 교체해가며 사용할 Context를 구현한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
// Strategy 객체를 참조하고 있는 Context 클래스
// Context
class Navigation {
private var routeAlgorithm: Strategy?

func execute() {
self.routeAlgorithm?.algorithmExecute()
}

func setStrategy(strategy: Strategy) {
self.routeAlgorithm = strategy
}
}
  • 실제로 사용해본다면?

런타임에서 계속해서 Strategy 객체를 변경하며 다른 알고리즘을 사용하는 것을 볼 수 있다.

Strategy Pattern의 장단점

장점

  • 런타임에서 객체 내부에서 사용되는 알고리즘을 변경 할 수 있다.
  • 알고리즘을 사용하는 코드와 알고리즘을 구현하는 코드를 분리할 수 있다.
  • Open / Closed Principle(개방 폐쇄 원칙)을 준수한다.
  • Context를 변경하지 않고도 새로운 Strategy를 도입할 수 있다.

단점

  • 알고리즘이 몇 개 없고 변경되는 일도 거의 없는 경우 전략 패턴의 도입이 오히려 복잡성을 증가시킬 수 있다.
  • 클라이언트가 적절한 Strategy를 선택하기 위해서는 각각의 차이점을 알고 있어야 한다.
  • Strategy, Context간 통신 오버헤드가 발생한다.

참고

Author

Sujeong Kim

Posted on

2021-10-20

Updated on

2021-10-22

Licensed under

댓글